package br.unicarioca.viaexpositus

class PerfilController extends BaseAutenticacao {

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

    def authenticateService

    static defaultAction = "list"

    @AnotacaoDeAcao(nomeDaAcao="Listar", padrao="ROLE_ADMINISTRADOR,ROLE_ORGANIZACAO")
    def list = {
        params.max = Math.min(params.max ? params.int('max') : 10, 100)

        def perfilInstanceList

        //Pegando a sessão do usuário
        Usuario usuarioLogado = getUsuario()
        if(usuarioLogado){
            if(usuarioLogado.organizacao){
                perfilInstanceList = Perfil.findAllByOrganizacao(usuarioLogado.organizacao)
            }else{
                perfilInstanceList = Perfil.list()
            }
        }

        [perfilInstanceList: perfilInstanceList, perfilInstanceTotal: perfilInstanceList.size()]
    }

    @AnotacaoDeAcao(nomeDaAcao="Salvar", padrao="ROLE_ADMINISTRADOR,ROLE_ORGANIZACAO")
    def save = {

        params.each{key, value ->
            println key+" --> "+value
        }

        def perfilInstance = new Perfil(params)

        //Gerando codenome do perfil, ROLE_*nome*
        perfilInstance.gerarCodeNome()
        preencherPermissoes(perfilInstance, params)

        //Pegando a sessão do usuário
        Usuario usuarioLogado = getUsuario()
        if(usuarioLogado?.organizacao){
            perfilInstance.organizacao = usuarioLogado.organizacao
        }

        if (perfilInstance.save(flush: true)) {
            flash.message = "${message(code: 'default.created.message', args: [message(code: 'perfil.label', default: 'Perfil'), perfilInstance.id])}"
            authenticateService.clearCachedRequestmaps()
            redirect(action: "list")
        } else {
            render(view: "edit", model: [perfilInstance: perfilInstance])
        }
    }

    @AnotacaoDeAcao(nomeDaAcao="Editar", padrao="ROLE_ADMINISTRADOR,ROLE_ORGANIZACAO")
    def edit = {

        if(params.id && params.id != "0"){
            def perfilInstance = Perfil.get(params.id)
            if (perfilInstance) {
                return [ perfilInstance : perfilInstance, mapa : servletContext.mapaDeAcoes]
            }else{
                flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'perfil.label', default: 'Perfil'), params.id])}"
                redirect(action: "list")
            }
        } else {
            def perfilInstance = new Perfil()
            return [perfilInstance: perfilInstance, mapa : servletContext.mapaDeAcoes]
        }
    }

    @AnotacaoDeAcao(nomeDaAcao="Atualizar", padrao="ROLE_ADMINISTRADOR,ROLE_ORGANIZACAO")
    def update = {
        def perfilInstance = Perfil.get(params.id)
        if (perfilInstance) {
            if (params.version) {
                def version = params.version.toLong()
                if (perfilInstance.version > version) {
                    
                    perfilInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'perfil.label', default: 'Perfil')] as Object[], "Another user has updated this Perfil while you were editing")
                    render(view: "edit", model: [perfilInstance: perfilInstance])
                    return
                }
            }
            perfilInstance.properties = params

            //Preenchendo as permissões e atualizando se neessário
            preencherPermissoes(perfilInstance, params)

            if (!perfilInstance.hasErrors() && perfilInstance.save(flush: true)) {
                flash.message = "${message(code: 'default.updated.message', args: [message(code: 'perfil.label', default: 'Perfil'), perfilInstance.id])}"
                authenticateService.clearCachedRequestmaps()
                redirect(action: "edit", id: perfilInstance.id)
            }
            else {
                render(view: "edit", model: [perfilInstance: perfilInstance])
            }
        }
        else {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'perfil.label', default: 'Perfil'), params.id])}"
            redirect(action: "list")
        }
    }

    @AnotacaoDeAcao(nomeDaAcao="Remover", padrao="ROLE_ADMINISTRADOR,ROLE_ORGANIZACAO")
    def delete = {
        def perfilInstance = Perfil.get(params.id)
        if (perfilInstance) {
            try {
                perfilInstance.delete(flush: true, failOnError:true)
                authenticateService.clearCachedRequestmaps()
                flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'perfil.label', default: 'Perfil'), params.id])}"
                redirect(action: "list")
            }
            catch (org.springframework.dao.DataIntegrityViolationException e) {
                flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'perfil.label', default: 'Perfil'), params.id])}"
                redirect(action: "edit", id: params.id)
            }
        }
        else {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'perfil.label', default: 'Perfil'), params.id])}"
            redirect(action: "list")
        }
    }

    /**
     * Preenche a lista de permissões do perfil passado.
     * Caso possua Id, e não veio checada, remove da lista.
     */
    private void preencherPermissoes(def perfilInstance, def params){

        //Bind das permissões deste perfil
        def qtd = params.findAll { key, value -> key.startsWith("listaDePermissao") && key.endsWith(".id") }.size()
        PermissaoHelper helper = new PermissaoHelper(qtd)
        bindData(helper, params)

        //Inicializando a lista de permissões para adicionar permissões obtidas
        if(!perfilInstance.listaDePermissoes){
            perfilInstance.listaDePermissoes = []
        }


        //TODO Colocar a adição como a remoção, utilizando o mesmo Perfil.
        
        def novasPermissoes = helper.listaDePermissao.findAll{!it.id && it.checked}
        def permissoesExistentesParaRemover = helper.listaDePermissao.findAll{it.id && !it.checked}

        
        novasPermissoes.each{

            //Configurando o valor do perfil, o codenome
            it.perfil = perfilInstance.codenome
            
            //Adicionando a permissão ao perfil
            perfilInstance.listaDePermissoes << it
        }
        
        //Removendo permissões que foram removidas da lista
        permissoesExistentesParaRemover.each{
            //Removendo a permissão ao perfil
            perfilInstance.listaDePermissoes -= it

            //Removendo o perfil da permissão
            def array = it.perfil.split(",")
            array -= perfilInstance.codenome
            it.perfil = array.join(",")

            if(it.perfil.size() < 4){
                it.delete(failOnError:true)
            }
        }

    }
}
